<?php

namespace App\Jobs;
use App\Http\Controllers\Live\ActivityController;
use App\Models\Live\LiveGroupModel;
use App\Models\Live\ShopMemberModel;
use App\Models\ShopHost;
use App\Models\ShopPointsChargeLog;
use App\Models\ShopPointsReceiveLog;
use App\Models\ShopPointsSendLog;
use App\Models\TencentAPIModel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class RunDBCreateJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $data;
    private $table;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct($table,$data)
    {
        $this->table=$table;
        $this->data=$data;
        $this->onQueue('before_points_send_job');
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //
        switch($this->table){
            case 'points_send_log':{
                $token=$this->data['token'];
                $room_id=$this->data['room_id'];
                $room_group_id=$this->data['room_group_id'];
                $shop_id=$this->data['shop_id'];
                $host_id=$this->data['host_id'];
                $shop_name=$this->data['shop_name'];
                $room_name=$this->data['room_name'];
                $host_name=$this->data['host_name'];
                $host_account=$this->data['host_account'];
                $points=$this->data['points'];
                $amount=$this->data['amount'];
                $point=$this->data['point'];
                $oprate_ip=$this->data['oprate_ip'];
                $cache_key_list=$this->data['cache_key_list'];
                $cache_key_grab_list=$this->data['cache_key_grab_list'];
                $cache_key_activity_current=$this->data['cache_key_activity_current'];
                $cache_key_activity_list=$this->data['cache_key_activity_list'];
                $time_long=$this->data['time_long'];//活动时长 默认60秒
                $countdown_timer=$this->data['countdown_timer'];//倒计时默认10秒钟
                $time_long=$countdown_timer+$time_long;
                $begin_time=time()+$countdown_timer;//积分活动开始时间 请求当下时间+倒计时
                $end_time=$begin_time+$time_long;//积分活动结束时间 请求当下时间+倒计时+1分钟
                $sender=ShopPointsSendLog::send([
                    'room_id'=>$room_id,
                    'room_group_id'=>$room_group_id,
                    'shop_id'=>$shop_id,
                    'host_id'=>$host_id,
                    'shop_name'=>$shop_name,
                    'room_name'=>$room_name,
                    'host_name'=>$host_name,
                    'host_account'=>$host_account,
                    'points'=>$points,
                    'amount'=>$amount,
                    'point'=>$point,
                    'countdown_timer'=>$countdown_timer,
                    'time_long'=>$time_long,
                    'begin_time'=>date('Y-m-d H:i:s',$begin_time),
                    'end_time'=>date('Y-m-d H:i:s',$end_time)
                ]);
                if(!empty($sender)){
                $activity_id=$sender->id;//当前活动批次ID
                $s="\r\n==========[0 RunDBCreateJob-发送积分 0]========\r\n";
                $s.="\r\n >>>>>> 房间：{$room_id}\r\n";
                $s.="\r\n >>>>>> 店铺：{$shop_id}\r\n";
                $s.="\r\n >>>>>> 主播：{$host_id}\r\n";
                $s.="\r\n >>>>>> 额度：{$points}\r\n";
                $s.="\r\n >>>>>> 份额：{$amount}\r\n";
                $s.="\r\n >>>>>> 平均：{$point}\r\n";
                $s.="\r\n >>>>>> 倒计时：".($countdown_timer)."\r\n";
                $s.="\r\n >>>>>> 开始：".(date('Y-m-d H:i:s',$begin_time))."\r\n";
                $s.="\r\n >>>>>> 结束：".(date('Y-m-d H:i:s',$end_time))."\r\n";
                $s.="\r\n==========[1 RunDBCreateJob-发送积分 1]========\r\n";
                            //循环写入每个平均积分发送列表ListKey
                            for($i=0;$i<$amount;$i++){Redis::RPUSH($cache_key_list,$point);}
                            if(!empty($countdown_timer)){
                            //设置积分发送列表ListKey到期时间（单位：秒）
                              Redis::EXPIRE($cache_key_list,$time_long);//立即发送 该数据一直存在 Job检测条件二(key_list和 begin_time这两个要保持 其余不是条件的可以不持久)
                            //设置积分发送列表的开始结束时间Key，Value保存开始和结束时间戳 到期是倒计时
                              Redis::SETEX($cache_key_list.'_begin_time',$time_long,$begin_time);//立即发送 该数据一直存在  检测条件一
                              Redis::SETEX($cache_key_list.'_end_time',$time_long,$end_time);
                              Redis::SETEX($cache_key_list.'_total',$time_long,$points);
                              Redis::SETEX($cache_key_list.'_average',$time_long,$point);
                              Redis::SETEX($cache_key_activity_current,$time_long,$activity_id);//当前房间的活动ID
                            }else{
                            //设置积分发送列表ListKey到期时间（单位：秒）
                              Redis::EXPIRE($cache_key_list,$time_long);//立即发送 该数据一直存在 Job检测条件二(key_list和 begin_time这两个要保持 其余不是条件的可以不持久)
                            //设置积分发送列表的开始结束时间Key，Value保存开始和结束时间戳 到期是倒计时
                              Redis::SETEX($cache_key_list.'_begin_time',$time_long,$begin_time);//立即发送 该数据一直存在  检测条件一
                              Redis::SETEX($cache_key_list.'_end_time',$time_long,$end_time);
                              Redis::SETEX($cache_key_list.'_total',$time_long,$points);
                              Redis::SETEX($cache_key_list.'_average',$time_long,$point);
                              Redis::SETEX($cache_key_activity_current,$time_long,$activity_id);//当前房间的活动ID
                            //   Redis::SET($cache_key_list.'_begin_time',$begin_time);//立即发送 该数据一直存在  Job检测条件一(key_list和 begin_time这两个要保持 其余不是条件的可以不持久)
                            //   Redis::SET($cache_key_list.'_end_time',$end_time);//立即发送 该数据一直存在  Job检测条件一(key_list和 begin_time这两个要保持 其余不是条件的可以不持久)
                            //   Redis::SET($cache_key_list.'_total',$points);//立即发送 该数据一直存在  Job检测条件一(key_list和 begin_time这两个要保持 其余不是条件的可以不持久)
                            //   Redis::SET($cache_key_list.'_average',$point);//立即发送 该数据一直存在  Job检测条件一(key_list和 begin_time这两个要保持 其余不是条件的可以不持久)
                            //   Redis::SET($cache_key_activity_current,$activity_id);//当前房间的活动ID
                            }
                            //{$shop_id} {$host_id} {$room_id} {$activity_id} {$end_time} {$points} {$amount} {$point}
                            Redis::RPUSH($cache_key_activity_list,"{$shop_id} {$host_id} {$room_id} {$activity_id} {$end_time} {$points} {$amount} {$point}");//把当前活动具体的ID列表加入到活动记录List列表

                            //重置积分领取列表 这里不手动清空当前批次的积分活动抢得列表 由后台任务进行处理 因为需要做积分如未抢完的积分退回操作
                            //Redis::DEL($cache_key_grab_list);
                            $deced=ShopHost::setPoints($host_id,[
                                'flag'=>'-',
                                'value'=>$points
                            ]);
                            if(!empty($deced)){
                            $before_value=$deced[0];
                            $after_value=$deced[1];
                            // 增加发放积分变化日志
                            $sender->status='ACTIVE';//当发送扣分后状态变化
                            $sender->save();//当发送扣分后状态变化
                            $tokenName=ActivityController::extractToken($token);
                            ShopPointsChargeLog::create([
                                    'shop_id'=>$shop_id,
                                    'shop_name'=>$shop_name,
                                    'host_id'=>$host_id,
                                    'host_name'=>$host_name,
                                    'host_account'=>$host_account,
                                    'change_name'=>'发放',
                                    'change_msg'=>'派发积分',
                                    'oprater_id'=>$token,
                                    'oprater_name'=>$tokenName,
                                    'oprate_ip'=>$oprate_ip,
                                    'oprate_flag'=>'-',
                                    'oprate_value'=>$points,
                                    'oprate_msg'=>'房ID：{'.$room_id.'}群ID：{'.$room_group_id.'}|派发{'.$points.'}个积分',
                                    'before_value'=>$before_value,
                                    'after_value'=>$after_value
                                ]
                            );
                            if(!env('API_TEST'))
                            LiveGroupModel::sendGroupMsg($room_group_id,[
                                'code' => 0, 
                                'type' => 'points',
                                'data'=>['rob_time'=>$begin_time,'start_time' => $countdown_timer, 'endTime' => $end_time,'message'=>'管理员发放了积分']]);
                                else{
                                    Log::debug("测试不群发\r\n");
                                }
                            Log::debug($s);
                            }
                }else{
                    $s="\r\n==========[0 RunDBCreateJob-Exception 0]========\r\n";
                    $s="\r\n >>>>>> [$this->table][".json_encode($this->data)."]\r\n";
                    Log::debug('积分发送活动DB创建异常');
                    $s="\r\n==========[1 RunDBCreateJob-Exception 1]========\r\n";
                }
                break;
            }
            case 'points_receive_log':{
                $cache_key_list=$this->data['cache_key_list'];
                $cache_key_grab_list=$this->data['cache_key_grab_list'];
                $token=$this->data['token'];
                $activity_id=$this->data['activity_id'];
                $room_id=$this->data['room_id'];
                $shop_id=$this->data['shop_id'];
                $host_id=$this->data['host_id'];
                $shop_name=$this->data['shop_name'];
                $room_name=$this->data['room_name'];
                $host_name=$this->data['host_name'];
                $receive_id=$this->data['receive_id'];
                $receive_name=$this->data['receive_name'];
                $points=$this->data['points'];
                $point=Redis::GET($cache_key_list.'_average');
                //这里需要注意如果发送错误 redis里面就扣减了 但是没有注入数据库
                //从积分发送列表ListKey领取积分

                //此处执行Online.Shop 数据的联动更新积分及积分记录DB操作 如果联动出错则不进行积分操作
                DB::beginTransaction();
                $db_v=ShopMemberModel::changePoints($receive_id,$point);
                if($db_v>0){
                   $receiver=ShopPointsReceiveLog::receive([
                     'activity_id'=>$activity_id,
                     'room_id'=>$room_id,
                     'shop_id'=>$shop_id,
                     'host_id'=>$host_id,
                     'shop_name'=>$shop_name,
                     'room_name'=>$room_name,
                     'host_name'=>$host_name,
                     'receive_id'=>$receive_id,
                     'receive_name'=>$receive_name,
                     'points'=>$points,
                     'point'=>$point,
                    ]);
                    if(!empty($receiver)){
                        $point=Redis::LPOP($cache_key_list);
                        Redis::SADD($cache_key_grab_list,$token);
                        $s="\r\n==========[0 RunDBCreateJob-抢积分 0]========\r\n";
                        $s.="\r\n >>>>>> 活动：{$activity_id}\r\n";
                        $s.="\r\n >>>>>> 房间：{$room_id}\r\n";
                        $s.="\r\n >>>>>> 店铺：{$shop_id}\r\n";
                        $s.="\r\n >>>>>> 主播：{$host_id}\r\n";
                        $s.="\r\n >>>>>> 用户：{$receive_id}\r\n";
                        $s.="\r\n >>>>>> 总积分：{$points}\r\n";
                        $s.="\r\n >>>>>> 均积分：{$point}\r\n";
                        $s.="\r\n >>>>>> ShopMemberModel::changePoints($receive_id,$point)：{$db_v}\r\n";
                        $s.="\r\n===>[1 RunDBCreateJob-抢积分 1]========\r\n";
                        Log::debug($s);
                        DB::commit();
                    }else{
                        $s="\r\n==========[0 RunDBCreateJob-Exception 0]========\r\n";
                        $s.="\r\n >>>>>> [$this->table][".json_encode($this->data)."]\r\n";
                        $s.="\r\n==========[1 RunDBCreateJob-Exception 1]========\r\n";
                        Log::debug('抢积分行为DB创建异常：积分记录创建异常'.$s);
                        DB::rollBack();
                    }
                }else{
                        $s="\r\n==========[0 RunDBCreateJob-Exception 0]========\r\n";
                        $s.="\r\n >>>>>> [$db_v]\r\n";
                        $s.="\r\n==========[1 RunDBCreateJob-Exception 1]========\r\n";
                        Log::debug('抢积分行为DB创建异常:Shop联动积分操作'.$s);
                        DB::rollBack();
                }
                break;
            }
        }
    }
    public function fail($exception = null)
    {
        $s="\r\n==========[0 RunDBCreateJob-Exception 0]========\r\n";
        $s="\r\n==========[$this->table][".json_encode($this->data)."]========\r\n";
        Log::debug($exception->getTraceAsString);
        $s="\r\n==========[1 RunDBCreateJob-Exception 1]========\r\n";
    }
}
